package GUI;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.TreeMap;

import javax.swing.DefaultListModel;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JOptionPane;
import javax.swing.JPasswordField;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.border.EmptyBorder;

import msgParser.Message;
import msgParser.Parser;
import msgParser.Strings;
import msgParser.Validation;

import Core.Connection;
import Core.Rank;
import Core.SessionData;

public class ForumMenu extends AbstractMenu
{
	private JLabel label;
	private JButton disconnectButton;
	private JLabel userMode;
	private JTextField userName;
	private JLabel userNameLabel;
	private JLabel userPassLabel;
	private JTextField userPass;
	private JButton loginButton;
	private JButton registerButton;
	private JButton refreshButton;
	private JButton activationButton;
	private JLabel userMailLabel;
	private JTextField userMail;
	private JLabel availableSubForums;
	private JList<String> subForumList;
	private JScrollPane subForumListScroll;
	private JButton lobbyButton;
	private JButton logoutButton;
	private JLabel loginTitle;
	private JLabel adminOptions;
	private JButton createSubForum;
	private JButton deleteSubForum;
	
	DefaultListModel<String> subForumListModel = new DefaultListModel<String>();  
	
	public ForumMenu(JFrame frame)
	{
		super(frame);
		
		label = new JLabel(MainWindow.data.currentForum);
		label.setBounds(400-MainWindow.data.currentForum.length()*10,30,300,30);
		label.setFont(new Font(label.getFont().getName(),label.getFont().getStyle(), 30));
		
		loginTitle = new JLabel("Login / Register to selected forum:");
		loginTitle.setBounds(30,110,300,30);
		loginTitle.setFont(new Font(loginTitle.getFont().getName(),loginTitle.getFont().getStyle(), 15));

		userNameLabel = new JLabel("User name:");
		userNameLabel.setBounds(30,140,100,30);
		userNameLabel.setFont(new Font(userNameLabel.getFont().getName(),userNameLabel.getFont().getStyle(), 15));
		
		userMailLabel = new JLabel("E-Mail:");
		userMailLabel.setBounds(30,200,100,30);
		userMailLabel.setFont(new Font(userMailLabel.getFont().getName(),userMailLabel.getFont().getStyle(), 15));
		
		userMail = new JTextField();
		userMail.setBounds(95, 205, 160, 25);
		userMail.setFont(new Font(userMail.getFont().getName(),userMail.getFont().getStyle(), 12));
		userMail.setForeground(new Color(140,140,140));
		userMail.setText("For registration only");
		userMail.addFocusListener(new FocusListener() {
			public void focusLost(FocusEvent arg0) {}
			public void focusGained(FocusEvent arg0) {
				if(userMail.getText().equals("For registration only")) 
				{
					userMail.setText("");
					userMail.setForeground(new Color(0,0,0));
				}
			}
		});
		
		userPassLabel = new JLabel("Password:");
		userPassLabel.setBounds(30,170,100,30);
		userPassLabel.setFont(new Font(userPassLabel.getFont().getName(),userPassLabel.getFont().getStyle(), 15));
		
		userName = new JTextField();
		userName.setBounds(135, 145, 120, 25);
		userName.setFont(new Font(userName.getFont().getName(),userName.getFont().getStyle(), 15));
		
		userPass = new JPasswordField();
		userPass.setBounds(135, 175, 120, 25);
		userPass.setFont(new Font(userPass.getFont().getName(),userPass.getFont().getStyle(), 15));
		
		loginButton = new JButton("Log In");
		loginButton.setBounds(116, 235, 70, 20);
		loginButton.addActionListener(new ActionListener() 
		{
            public void actionPerformed(ActionEvent e)
            {
            	String forum = MainWindow.data.currentForum;
            	if(!Validation.validateString(userName.getText(), Validation.CHAR_FIRST | Validation.NO_SPACES | Validation.NO_SYMBOLS | Validation.HAS_LETTERS))
        		{
        			JOptionPane.showMessageDialog(null, "User name should start with a letter and contain no symbols or spaces.", "Invalid user name", JOptionPane.ERROR_MESSAGE);
            		return;
        		}
        		if(!Validation.validateString(userPass.getText(), Validation.NO_SPACES | Validation.HAS_LETTERS))
        		{
        			JOptionPane.showMessageDialog(null, "Password should start with a letter and contain no spaces.", "Invalid password", JOptionPane.ERROR_MESSAGE);
            		return;
        		}
        		MainWindow.data.currentSelectedForum = forum;
            	Connection.send(Message.createMessage(Strings.LOG_IN, userName.getText(), userPass.getText(), 
            						""+MainWindow.data.forums.get(forum)));
            }
		});
		
		activationButton = new JButton("Activate");
		activationButton.setBounds(190, 235, 85, 20);
		activationButton.addActionListener(new ActivationDialog());
		
		registerButton = new JButton("Register");
		registerButton.setBounds(27, 235, 85, 20);
		registerButton.addActionListener(new ActionListener() 
		{
            public void actionPerformed(ActionEvent e)
            {
            	String forum = MainWindow.data.currentForum;
            	if(!Validation.validateString(userName.getText(), Validation.CHAR_FIRST | Validation.NO_SPACES | Validation.NO_SYMBOLS | Validation.HAS_LETTERS))
        		{
        			JOptionPane.showMessageDialog(null, "User name should start with a letter and contain no symbols or spaces.", "Invalid user name", JOptionPane.ERROR_MESSAGE);
            		return;
        		}
        		if(!Validation.validateString(userPass.getText(), Validation.NO_SPACES | Validation.HAS_LETTERS))
        		{
        			JOptionPane.showMessageDialog(null, "Password should start with a letter and contain no spaces.", "Invalid password", JOptionPane.ERROR_MESSAGE);
            		return;
        		}
        		if(!Validation.validateString(userMail.getText(), Validation.NO_SPACES | Validation.HAS_LETTERS | Validation.IS_MAIL))
        		{
        			JOptionPane.showMessageDialog(null, "E-Mail address is invalid.", "Invalid Email", JOptionPane.ERROR_MESSAGE);
            		return;
        		}
            	int dialogResult = JOptionPane.showConfirmDialog (null, "Register to " + forum + "?","Confirm Registration",JOptionPane.WARNING_MESSAGE);
            	if(dialogResult == JOptionPane.YES_OPTION)
            	{
            		
            		Connection.send(Message.createMessage(Strings.REGISTER, userName.getText(), userPass.getText(), 
            						userMail.getText(), ""+MainWindow.data.forums.get(forum)));
            	}
            }
		});
		
		logoutButton = new JButton("Log out");
		logoutButton.setBounds(25, 140, 100, 20);
		logoutButton.addActionListener(new ActionListener() 
		{
            public void actionPerformed(ActionEvent e)
            {
            	Connection.send(Message.createMessage(Strings.LOGOUT));
            }
		});
		
		adminOptions = new JLabel("Administrator options:");
		adminOptions.setBounds(25,180,300,30);
		adminOptions.setFont(new Font(adminOptions.getFont().getName(),adminOptions.getFont().getStyle(), 15));
		
		userMode = new JLabel(MainWindow.data.rank.toString() + " mode");
		userMode.setBounds(10,500,200,30);
		userMode.setFont(new Font(userMode.getFont().getName(),userMode.getFont().getStyle(), 15));
		userMode.setForeground(new Color(0, 0, 255));
		
		availableSubForums = new JLabel("Available sub-forums:");
		availableSubForums.setBounds(350,110,200,30);
		availableSubForums.setFont(new Font(availableSubForums.getFont().getName(),availableSubForums.getFont().getStyle(), 15));
		
		createSubForum = new JButton("Create Sub-Forum");
		createSubForum.setBounds(25, 210, 160, 20);
		createSubForum.addActionListener(new ActionListener() 
		{
            public void actionPerformed(ActionEvent e)
            {
            	MainWindow.switchMenu(new CreateSubForumMenu(getFrame()));
            }
		});
		

		deleteSubForum = new JButton("Remove Sub-Forum");
		deleteSubForum.setBounds(25, 240, 160, 20);
		deleteSubForum.addActionListener(new ActionListener() 
		{
            public void actionPerformed(ActionEvent e)
            {
            	if(subForumList.getSelectedIndex() == -1)
            	{
            		JOptionPane.showMessageDialog(null, "Please select a sub-forum.", "Error", JOptionPane.ERROR_MESSAGE);
            		return;
            	}
            	int dialogResult = JOptionPane.showConfirmDialog (null, "Remove " + MainWindow.data.currentSelectedSubForum + "?","Confirm removal",JOptionPane.WARNING_MESSAGE);
            	if(dialogResult == JOptionPane.YES_OPTION)
            	{
            		Connection.send(Message.createMessage(Strings.REMOVE_SUBFORUM, ""+MainWindow.data.subForums.get(MainWindow.data.currentSelectedSubForum)));
            	}
            }
		});
		
		lobbyButton = new JButton("Back to Lobby");
		lobbyButton.setBounds(660, 115, 130, 20);
		lobbyButton.addActionListener(new ActionListener() 
		{
            public void actionPerformed(ActionEvent e)
            {
            	MainWindow.switchMenu(new LobbyMenu(getFrame()));
            }
		});
		
		
		subForumList = new JList<String>(subForumListModel);
		subForumList.setBorder(new EmptyBorder(4,4,4,4));
		subForumList.setFixedCellHeight(30);
		subForumList.setFixedCellWidth(100);
		//subForumList.setBounds(350, 140, 300, 400);
		subForumList.setFont(new Font("Courier New",subForumList.getFont().getStyle(), 18));
		subForumListScroll = new JScrollPane(subForumList, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
                JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
		subForumListScroll.setPreferredSize(new Dimension(300, 100));
		subForumListScroll.setBounds(350, 140, 300, 400);
		subForumList.addMouseListener(new MouseAdapter() {
		    public void mouseClicked(MouseEvent evt) {
		        JList<String> list = (JList<String>)evt.getSource();
		        if(evt.getClickCount() == 1)
		        {
		        	int index = list.locationToIndex(evt.getPoint());
		        	if(index < 0) return;
		        	String name = subForumListModel.get(index);
		        	MainWindow.data.currentSelectedSubForum = name;
		        }
		        else if(evt.getClickCount() == 2) 
		        {         
		        	int index = list.locationToIndex(evt.getPoint());
		        	if(index < 0) return;
		        	String name = subForumListModel.get(index);
		        	MainWindow.data.currentSubForum = name;
		        	MainWindow.switchMenu(new SubForumMenu(getFrame()));
		        } 
		        
		    }
		});
		
		disconnectButton = new JButton(new ImageIcon("disconnect.PNG"));
		disconnectButton.setBounds(10, 530, 32, 32);
		disconnectButton.setContentAreaFilled(false);
		disconnectButton.setBorder(null);
		disconnectButton.addMouseListener(new MouseAdapter() 
		{
		    public void mousePressed(MouseEvent evt) 
		    {
		    	disconnectButton.setIcon(new ImageIcon("disconnect2.PNG"));
            	disconnectButton.repaint();
		    }
		    public void mouseReleased(MouseEvent evt) 
		    {
		    	Point p = evt.getPoint();
		    	disconnectButton.setIcon(new ImageIcon("disconnect.PNG"));
            	disconnectButton.repaint();
		    	if(p.x < 0 || p.y < 0 || p.x > disconnectButton.getWidth() || p.y > disconnectButton.getHeight()) return;
            	Connection.disconnect();
            	MainWindow.data = new SessionData();
            	MainWindow.switchMenu(new ConnectMenu(getFrame()));
		    }
		});
		
		refreshButton = new JButton(new ImageIcon("refresh.PNG"));
		refreshButton.setBounds(650, 510, 30, 30);
		refreshButton.addActionListener(new ActionListener() 
		{
            public void actionPerformed(ActionEvent e)
            {
            	Connection.send(Message.createMessage(Strings.SHOW_SUBFORUMS, ""+MainWindow.data.forums.get(MainWindow.data.currentForum)));
            }
		});
		
	}


	public void connectionInterrupted() 
	{
		JOptionPane.showMessageDialog(null, "Connection has crashed. Please reconnect...", "Connection Error", JOptionPane.ERROR_MESSAGE);
		MainWindow.switchMenu(new ConnectMenu(getFrame()));
	}

	public void incomingMessage(String msg) 
	{
		//JOptionPane.showMessageDialog(null, msg, "W00T", JOptionPane.ERROR_MESSAGE);
		Parser p = new Parser(msg);
		p.Parse();
		try 
		{
			if(p.testHeader(Strings.ANS_SHOW_SUBFORUMS))
			{
				subForumListModel.clear();
				subForumListModel.addElement("FIX");
				subForumListModel.remove(0);
				TreeMap<String, Integer> subForums = new TreeMap<String, Integer>();
				for(int i = 1; i < p.getSize(); i+=2) 
				{
					subForums.put(p.argStr(i), p.argInt(i+1));
					subForumListModel.addElement(p.argStr(i));
				}
				MainWindow.data.subForums = subForums;
				
			}
			else if(p.testHeader(Strings.ACTIVATION_NEEDED))
			{
				JOptionPane.showMessageDialog(null, "According to the forum policy, activation via E-mail is required.\nPlease click 'Activation' to activate your account.", "Activation Needed", JOptionPane.INFORMATION_MESSAGE);
				userName.setText("");
				userPass.setText("");
			}
			else if(p.testHeader(Strings.REGISTERED))
			{
				JOptionPane.showMessageDialog(null, "Registration successful. You may now login.", "Success", JOptionPane.INFORMATION_MESSAGE);
				userName.setText("");
				userPass.setText("");
			}
			else if(p.testHeader(Strings.ERROR_REGISTER))
			{
				JOptionPane.showMessageDialog(null, "Registration error: " + p.argStr(1), "Unexpected error", JOptionPane.ERROR_MESSAGE);
				userName.setText("");
				userPass.setText("");
			}
			else if(p.testHeader(Strings.LOGGED_IN))
			{
				int userId = p.argInt(1);
				int rank = p.argInt(2);
				MainWindow.data.myUserId = userId;
				MainWindow.data.loggedIn = true;
				MainWindow.data.rank = Rank.create(rank);
				JOptionPane.showMessageDialog(null, "You are now logged in as " + userName.getText() + ".", "Success", JOptionPane.INFORMATION_MESSAGE);
				MainWindow.switchMenu(new ForumMenu(getFrame()));
			}
			else if(p.testHeader(Strings.ERROR_LOG_IN))
			{
				JOptionPane.showMessageDialog(null, "Login error: " + p.argStr(1), "Unexpected error", JOptionPane.ERROR_MESSAGE);
				userName.setText("");
				userPass.setText("");
			}
			else if(p.testHeader(Strings.LOGGED_OUT))
			{
				MainWindow.data.loggedIn = false;
				MainWindow.data.rank = Rank.GUEST;
				JOptionPane.showMessageDialog(null, "You have logged out of the system.", "Logged out", JOptionPane.INFORMATION_MESSAGE);
				MainWindow.switchMenu(new LobbyMenu(getFrame()));
			}
			else if(p.testHeader(Strings.ERROR_LOG_OUT))
			{
				JOptionPane.showMessageDialog(null, "Logout error: " + p.argStr(1), "Unexpected error", JOptionPane.ERROR_MESSAGE);
			}
			else if(p.testHeader(Strings.ERROR_REMOVE_SUBFORUM))
			{
				JOptionPane.showMessageDialog(null, "Removal error: " + p.argStr(1), "Unexpected error", JOptionPane.ERROR_MESSAGE);
			}
			else if(p.testHeader(Strings.SUBFORUM_REMOVED))
			{
				Connection.send(Message.createMessage(Strings.SHOW_SUBFORUMS, ""+MainWindow.data.forums.get(MainWindow.data.currentForum)));
			}
		} 
		catch (Exception e) {}
	}


	public void create() 
	{
		regItem(label);
		if(MainWindow.data.rank.getValue()==0)
		{
			regItem(userName);
			regItem(userPass);
			regItem(userNameLabel);
			regItem(userPassLabel);
			regItem(loginButton);
			regItem(registerButton);
			regItem(lobbyButton);
			regItem(loginTitle);
			regItem(activationButton);
			regItem(userMail);
			regItem(userMailLabel);
		}
		else
		{
			if(MainWindow.data.rank.getValue() > 1)
			{
				
			}
			regItem(logoutButton);
			
			regItem(adminOptions);
			regItem(createSubForum);
			regItem(deleteSubForum);
			
		}
		regItem(subForumListScroll);
		regItem(refreshButton);
		regItem(availableSubForums);
		regItem(disconnectButton);
		regItem(userMode);
		
		
		getFrame().repaint();
		Connection.send(Message.createMessage(Strings.SHOW_SUBFORUMS, ""+MainWindow.data.forums.get(MainWindow.data.currentForum)));
	}

}
